# coding=utf-8

import web
from web.utils import storage

from weibo import APIClient, APIError

import utils
import settings

# 用户数据接口
import models

__all__ = ('UserSession',)

# TODO: 表示一个用户会话对象
class UserSession(object):
    def __init__(self):
        # 用户在猫克斯上的id
        self.uid = 0
        # 用户在新浪微博的授权令牌会话
        # self.token 是一个json，
        # 包含：
        #       access_token:   接口实际需要得授权码
        #       expires_in:     授权超时时间
        #       uid:            用户id
        #       以上参数均是 string 类型
        self.token = False
        # 用户名
        self.name = False
        # 当前会话的新浪微博客户端对象
        self._client = False
        # 读取cookie
        self._resolve_cookie()

    # TODO: 获取cookie中的信息
    def _resolve_cookie(self):
        val = utils.decrypt(web.cookies().get('su', None))
        if val:
            vals = val.split('|')
            if len(vals) == 4:
                self.uid = long(vals[0])
                self.token = storage(access_token = vals[1],
                        expires_in = vals[2],
                        uid = vals[3])
            # 获取保存在cookie中的昵称
            self.name = web.cookies().get('name', 'N/A')

    # TODO: 表示当前会话用户是否登录
    def _is_logined(self):
        return self.uid > 0 and self.token.access_token and self.token.uid

    # TODO: 表示当前会话用户是否登录
    logined = property(_is_logined)

    # TODO: 退出当前会话用户的登录状态
    def logout(self, redir = '/'):
        # 清空cookie
        web.setcookie('su', None)
        if redir:
            # 转向到给定页
            raise web.seeother(redir)

    # TODO: 获取当前会话的用户
    def resolve_info(self):
        return None

    # TODO: 创建微博客户端
    def _create_client(self):
        if not self._client:
            self._client = APIClient(settings.SINA_APP_KEY,
                    settings.SINA_APP_SECRET, 
                    utils.format_absurl('/login'))
        return self._client

    client = property(_create_client)

    # TODO: OAuth验证成功后保存登录状态
    # @code string 微博登录返回的令牌码
    def oauth_save_login(self, code):
        # 获取授权用户信息
        try:
            self.token = self.client.request_access_token(code)
        except APIError, e:
            return False
        if self.token:
            # 先从微博获取用户信息
            self.client.set_access_token(self.token.access_token
                    , self.token.expires_in)
            # 获取微博用户信息
            wbusr = self.client.get.users__show(uid = self.token.uid)
            if not wbusr:
                # 如果对应的用户不存在
                # 直接失败
                return False

            # 获取数据库中用户信息
            usr = models.get_user_by_weibo_id(self.token.uid)
            if usr:
                # 如果找到相关用户，那么更新一下数据库中的信息
                models.update_user_from_weibo_callback(usr.id, wbusr)
                # 这里直接更新返回得用户对象，避免修改后再读一次数据库
                usr.screen_name = wbusr.screen_name
            else:
                # 没有获取到用户
                # 自动进行注册
                # 添加到数据库中
                usr = models.add_user_from_weibo_callback(wbusr)
            if usr:
                # 数据库添加成功
                # 写入cookie
                # 核心cookie，security user 缩写
                web.setcookie('su'
                        , utils.encrypt('%s|%s|%s|%s' % (usr.id
                                            , self.token.access_token
                                            , self.token.expires_in
                                            , self.token.uid) ))
                # 写入用户昵称到cookie方便到处调用
                # 这里就不加密了
                web.setcookie('name', usr.screen_name)
                # 设置相关值到当前会话实例中
                self.uid = usr.id
                self.name = usr.screen_name
                # 返回成功信息
                return True
        return False

    # TODO: 初始化新浪 OAuth 认证对象
    def oauth_init(self):
        # 返回用户验证url
        return self.client.get_authorize_url()

    # TODO: 获取当前会话用户（静态方法）
    @staticmethod
    def current():
        return UserSession()

# 存入一个获取当前登录用户到模板引擎中
web.template.Template.globals['current_user'] = UserSession.current
